package cluedo.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
//import java.awt.event.ActionEvent;
//import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
//import javax.swing.Timer;

import cluedo.Pawn;
import cluedo.Room;

/** Una casella del tabellone */
public class Cell extends JPanel implements ComponentListener{
	
	private static final long serialVersionUID = -113591655557767670L;

	/**
	 * Contiene l'immagine della pedina
	 */
	private JLabel imgLabel;
	
	/**
	 * la pedina attualmente sulla casella oppure null se la casella non contiene alcuna pedina
	 */
	private Pawn pawn=null;
	
	/**
	 * La cella e' in una stanza
	 */
	private boolean isRoom=false;
	
	/**
	 * Contiene il nome della stanza di cui la cella fa parte oppure di cui la cella e' l'entrata
	 */
	private String nameRoom = null;
	
	/**
	 * verifica se si possono muovere pedine su questa cella
	 */
	private boolean isUsable=false;
	
	/**
	 * la cella e' l'ingresso di una stanza?
	 */
	private boolean isEntrance=false;
		
	/**
	 * la cella e' evidenziata?
	 */
	private boolean isHighlighted=false;
	
	/**
	 * il tabellone di cui la cella fa parte
	 */
	private BoardPanel board;
	
	/**
	 * la coordinata x associata a questa cella
	 */
	
	private int x;
	
	/**
	 * la coordinata y associata a questa cella
	 */
	
	private int y;
	
	/**
	 * timer che gestisce lampeggiamento cella
	 */
	
	//private Timer timer;
	
	/**
	 * Costruttore usato dalle celle libere oppure non utilizzabili dalle pedine
	 * @param isUsable true oppure false a seconda che la cella possa contenere una pedina
	 * @param bd  (board) il tabellone
	 * @param x la coordinata x associata a questa cella
	 * @param y la coordinata y associata a questa cella
	 */
	public Cell(boolean isUsable,BoardPanel bd,int x, int y) {
		
		imgLabel=new JLabel();
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		
		Component rigidArea= Box.createRigidArea(new Dimension(
				(int)((bd.getBgWidth()/bd.getCols())*0.1),0));
		add(rigidArea);
		
		add(imgLabel);
		
		Color c = new Color (255, 255, 0, 50); //giallo, alpha 50%
		setBackground(c);
		setPreferredSize(new Dimension(bd.getBgWidth()/bd.getCols(),bd.getBgHeight()/bd.getRows()));
		this.board=bd;
		this.x=x;
		this.y=y;
		addComponentListener(this);
		setOpaque(false); //trasparente
		this.isUsable=isUsable;
		
	}
		
	
	/**
	 * Costruttore usato dalle celle che fanno parte di una stanza o che sono l'entrata della stanza
	 * @param nameRoom il nome della stanza di cui fa parte la cella oppure di cui la cella e' l'entrata
	 * @param isEntrance true se e' l'ingresso di una stanza, false altrimenti
	 * @param board il tabellone
	 * @param x la coordinata x associata a questa cella
	 * @param y la coordinata y associata a questa cella
	 */
	public Cell(String nameRoom, boolean isEntrance, BoardPanel board,int x, int y){
		
		this(true,board,x,y);
		if(!isEntrance)
			this.isRoom=true;
		else
			this.isEntrance=true;
		if(Room.rooms.containsKey(nameRoom)){
			this.nameRoom=nameRoom;
		}else{
			System.err.println("Cell: Il nome della stanza inserita non e' valido");
		}
	}
	
	/**
	 * Controllo se e' l'entrata di una stanza
	 * @return true se e' l'entrata, false altrimenti
	 */
	public boolean isEntrance(){
		return this.isEntrance;
	}
	
	/**
	 * Controlla se una casella e' vuota
	 * @return true se la casella e' vuota, false altrimenti
	 */
	public boolean isEmpty(){
		
		return(pawn==null);
		
	}
	
	
	/**
	 * Ritorna la pedina sulla cella o null se la cella e' vuota
	 * @return vedi descrizione
	 */
	public Pawn getPawn(){
		
		return pawn;
		
	}
	
	
	/**
	 * Restituisce il nome della stanza di cui fa parte la cella
	 * @return vedi descrizione metodo
	 */
	public String getRoomName(){
		
		return nameRoom;
	}
	
	/**
	 * Restituisce la coordinata x associata a questa cella
	 * @return vedi descrizione
	 */
	public int getXCoord(){
		return this.x;
	}
	
	
	/**
	 * Restituisce la coordinata y associata a questa cella
	 * @return vedi descrizione
	 */
	public int getYCoord(){
		return this.y;
	}
	
	
	/**
	 * Controlla se la cella corrente e' nella stessa stanza della cella passata come parametro
	 * @param cell la casella da confrontare
	 * @return true se le celle sono nella stessa stanza, false altrimenti
	 */
	public boolean isSameRoom(Cell cell){
		
		if(isRoom && cell.isInRoom()){
			if(nameRoom.equals(cell.getRoomName()))
				return true;
		}
		
		return false;
	}
	
	
	/**
	 * Controlla se la cella fa parte di una stanza
	 * @return true se la cella fa parte di una stanza, false altrimenti
	 */
	public boolean isInRoom(){
		
		return this.isRoom;
	}
	
	/**
	 * Aggiunge una pedina nella casella
	 * @return true se la pedina e' stata aggiunta, false altrimenti
	 */
	public boolean insertPawn(Pawn p){
		
		if(isUsable && pawn==null){
		
			this.pawn=p;
			if(isRoom)
				p.setIsInRoom(true);
					
			imgLabel.setIcon(p.getScaledImage(
				    (int)((board.getBgWidth()/board.getCols())*0.8),(int)((board.getBgHeight()/board.getRows())*0.8)));
			return true;
		}
		
		return false;
	}
	
	/** Rimuove la pedina dalla casella */
	public void removePawn(){
		if(pawn!=null){
			pawn=null;
			imgLabel.setIcon(null);
		}
	}
	
	
	/**
	 * Evidenzia la cella per mostrare che la pedina puo' essere spostata sopra di questa
	 */
	public void highlightCell(){
			/*timer = new Timer(500, new TimerListener(this)); 
			timer.start();*/
			setOpaque(true);
			if(isRoom)
				setBorder(BorderFactory.createLineBorder(Color.CYAN,3));
			else
				setBorder(BorderFactory.createLineBorder(Color.YELLOW));
			
			//attiva il mouse listener per la cella
			
			if(!isHighlighted) //evita di rischiare di aggiungere piu' di una volta il MouseListener
				addMouseListener(board); 
			isHighlighted=true;
			board.revalidate();
			board.repaint();
					
	}
	
	/**
	 * controlla se la cella e' evidenziata
	 * @return vedi descrizione
	 */
	public boolean isHighlighted(){
	
		return this.isHighlighted; 
		
	}
	
	
	/**
	 * Controlla se la cella puo' ospitare una pedina (N.B. e' diverso da isEmpty() che dice se la cella e' libera)
	 * @return true se una pedina puo' fermarsi sulla cella, false altrimenti
	 */
	public boolean isUsable(){
		
		return this.isUsable;
		
	}
	
	
	/**
	 * Rimuovi la messa in luce della cella
	 */
	public void removeHighlight(){
	
		/*timer.stop();
		if(isOpaque()){
			setOpaque(false);
			setBorder(null);
		}*/
		setOpaque(false);
		setBorder(null);
		removeMouseListener(board);
		isHighlighted=false;
		board.revalidate();
		board.repaint();
		
		
	}


	@Override
	public void componentResized(ComponentEvent e) {

		setPreferredSize(new Dimension(board.getBgWidth()/board.getCols(),board.getBgHeight()/board.getRows()));
		
		if(pawn!=null){
			
			imgLabel.setIcon(pawn.getScaledImage(
					(int)((board.getBgWidth()/board.getCols())*0.8),(int)((board.getBgHeight()/board.getRows())*0.8)));
			
		}
		
	}


	@Override
	public void componentMoved(ComponentEvent e) {
		
	}


	@Override
	public void componentShown(ComponentEvent e) {
		
	}


	@Override
	public void componentHidden(ComponentEvent e) {
		
	}
	
	
	/***
	 * Il listener per gestire il timer
	 *
	 */
/*	private class TimerListener implements ActionListener {
		
		Cell thisCell;
		
		public TimerListener(Cell c){
			thisCell=c;
		}
		
		public void actionPerformed(ActionEvent e) {
			
		
			if(!thisCell.isOpaque()){
			thisCell.setOpaque(true);
			setBorder(BorderFactory.createLineBorder(Color.YELLOW));
			}
			else{
				thisCell.setOpaque(false);
				setBorder(null);
			}
			board.revalidate();
			board.repaint();
		}
	}*/
	

}
